// 框架附属代码
define(function (require, exports, module) {
    'use strict';
    var $ = require('jquery'),
        Backbone = require('backbone'),
        utils = require('js/utils/tools');
    require('jquery-ui');
    require('nanoscroller');
    require('multiselect');
    // Variables
    var Body = $('body');

    // jQuery Helper Functions
    var runHelpers = function () {

        // Disable selection
        $.fn.disableSelection = function () {
            return this
                .attr('unselectable', 'on')
                .css('user-select', 'none')
                .on('selectstart', false);
        };

        // Test for IE, Add body class if version 9
        function msieversion() {
            var ua = window.navigator.userAgent;
            var msie = ua.indexOf("MSIE ");
            if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) {
                var ieVersion = parseInt(ua.substring(msie + 5, ua.indexOf(".", msie)));
                if (ieVersion === 9) {
                    $('body').addClass('no-js ie' + ieVersion);
                }
                return ieVersion;
            } else {
                return false;
            }
        }
        msieversion();

        // Clean up helper that removes any leftover
        // animation classes on the primary content container
        // If left it can cause z-index and visibility problems
        setTimeout(function () {
            $('#content').removeClass('animated fadeIn');
        }, 500);

    };

    // Delayed Animations
    var runAnimations = function () {

        // Add a class after load to prevent css animations
        // from bluring pages that have load intensive resources
        setTimeout(function () {
            $('body').addClass('onload-check');
        }, 100);

        // Delayed Animations
        // data attribute accepts delay(in ms) and animation style
        // if only delay is provided fadeIn will be set as default
        // eg. data-animate='["500","fadeIn"]'
        $('.animated-delay[data-animate]').each(function () {
            var This = $(this);
            var delayTime = This.data('animate');
            var delayAnimation = 'fadeIn';

            // if the data attribute has more than 1 value
            // it's an array, reset defaults
            if (delayTime.length > 1 && delayTime.length < 3) {
                delayTime = This.data('animate')[0];
                delayAnimation = This.data('animate')[1];
            }

            var delayAnimate = setTimeout(function () {

                This.removeClass('animated-delay').addClass('animated ' + delayAnimation)
                    .one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function () {
                        This.removeClass('animated ' + delayAnimation);
                    });

            }, delayTime);
        });

        // "In-View" Animations
        // data attribute accepts animation style and offset(in %)
        // eg. data-animate='["fadeIn","40%"]'
        $('.animated-waypoint').each(function (i, e) {
            var This = $(this);
            var Animation = This.data('animate');
            var offsetVal = '35%';

            // if the data attribute has more than 1 value
            // it's an array, reset defaults
            if (Animation.length > 1 && Animation.length < 3) {
                Animation = This.data('animate')[0];
                offsetVal = This.data('animate')[1];
            }

            var waypoint = new Waypoint({
                element: This,
                handler: function (direction) {
                    console.log(offsetVal);
                    if (This.hasClass('animated-waypoint')) {
                        This.removeClass('animated-waypoint').addClass('animated ' + Animation)
                            .one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function () {
                                This.removeClass('animated ' + Animation);
                            });
                    }
                },
                offset: offsetVal
            });
        });

    };

    // Header Functions
    var runHeader = function () {

        // Searchbar - Mobile modifcations
        $('.navbar-search').on('click', function (e) {
            var This = $(this);
            var searchForm = This.find('input');
            var searchRemove = This.find('.search-remove');

            // Don't do anything unless in mobile mode
            if (!$('body.mobile-view').length) {
                return;
            }

            // Open search bar and add closing icon if one isn't found
            This.addClass('search-open');
            if (!searchRemove.length) {
                This.append('<div class="search-remove"></div>');
            }

            // Fadein remove btn and focus search input on animation complete
            setTimeout(function () {
                This.find('.search-remove').fadeIn();
                searchForm.focus();
                searchForm.one('keydown', function () {
                    $(this).val('');
                });
            }, 330);

            // If remove icon clicked close search bar
            if ($(e.target).attr('class') == 'search-remove') {
                This.removeClass('search-open');
                This.find('.search-remove').remove();
            }

        });

        // custom animation for header content dropdown
        if ($('.dropdown-item-slide').length) {
            $('.dropdown-item-slide').on('shown.bs.dropdown', function () {
                var This = $(this);
                setTimeout(function () {
                    This.addClass('slide-open');
                }, 20);
            });
            $('.dropdown-item-slide').on('hidden.bs.dropdown', function () {
                $(this).removeClass('slide-open');
            });
        }

        // Init jQuery Multi-Select for navbar user dropdown
        if ($("#user-status").length) {
            $('#user-status').multiselect({
                buttonClass: 'btn btn-default btn-sm',
                buttonWidth: 100,
                dropRight: false
            });
        }
        if ($("#user-role").length) {
            $('#user-role').multiselect({
                buttonClass: 'btn btn-default btn-sm',
                buttonWidth: 100,
                dropRight: true
            });
        }

        // Persistent tooltips. Use this class to prevent a menu
        // dropdown from closing when clicking content inside of it
        if ($('.dropdown-menu.dropdown-persist').length) {
            $('.dropdown-menu.dropdown-persist').on('click', function (e) {
                e.stopPropagation();
                var Target = $(e.target);

                // stopping event propagation will also disable multiselects from working
                // in areas such as the user menu dropdown. This helps correct that
                function closeMulti() {
                    Target.parents('.dropdown-persist').find('.btn-group').each(function () {
                        if ($(this).children('.multiselect').length) {
                            $(this).removeClass('open');
                        }
                    });
                }

                if (Target.hasClass('multiselect') || Target.parent().hasClass('multiselect')) {
                    closeMulti();
                    Target.parents('.btn-group').toggleClass('open');
                } else {
                    closeMulti()
                }
            });
        }

        // Sliding Topbar Metro Menu
        var menu = $('#topbar-dropmenu');
        var items = menu.find('.metro-tile');
        var metroBG = $('.metro-modal');

        // Toggle menu and active class on icon click
        $('.topbar-menu-toggle').on('click', function () {

            menu.slideToggle(230).toggleClass('topbar-menu-open');
            $(items).addClass('animated animated-short fadeInDown').css('opacity', 1);

            // Create Modal for hover effect
            if (!metroBG.length) {
                metroBG = $('<div class="metro-modal"></div>').appendTo('body');
            }
            setTimeout(function () {
                metroBG.fadeIn();
            }, 380);

        });

        // If modal is clicked close menu
        $('body').on('click', '.metro-modal', function () {
            metroBG.fadeOut('fast');
            setTimeout(function () {
                menu.slideToggle(150).toggleClass('topbar-menu-open');
            }, 250);
        });
    };

    // SideMenu Functions
    var runSideMenu = function (options) {

        // If Nano scrollbar exist and sidebar is fixed init plugin
        if ($('.nano.affix').length) {
            $(".nano").nanoScroller({
                preventPageScrolling: true
            });
        }

        // Sidebar state naming conventions:
        // "sb-l-o" - SideBar Left Open
        // "sb-l-c" - SideBar Left Closed
        // "sb-l-m" - SideBar Left Minified
        // Same naming convention applies to right sidebar

        // SideBar Left Toggle Function
        var sidebarLeftToggle = function () {

            // We check to see if the the user has closed the entire
            // leftside menu. If true we reopen it, this will result
            // in the menu resetting itself back to a minified state.
            // A second click will fully expand the menu.
            if (Body.hasClass('sb-l-c') && options.collapse === "sb-l-m") {
                Body.removeClass('sb-l-c');
            }

            // Toggle sidebar state(open/close)
            Body.toggleClass(options.collapse);

            triggerResize();
        };

        // SideBar Right Toggle Function
        var sidebarRightToggle = function (e) {

            // toggle sidebar state(open/close)
            e.preventDefault();
            Body.toggleClass('sb-r-o sb-r-c');
            if (options.siblingsRope === true && !Body.hasClass('mobile-view')) {
                if (Body.hasClass('sb-r-o sb-l-o')) {
                    Body.removeClass('sb-l-o').addClass('sb-l-m');
                }
            }
            var key = ($('#sidebar_right').data('key') || utils.getCurrentKey()) + '_align';
            localStorage.setItem(key, Body.hasClass('sb-r-o') ? 'o' : 'c');

            triggerResize();
            return false;
        };

        // Sidebar Left Collapse Entire Menu event
        $('.sidebar-toggle-mini').on('click', function (e) {
            e.preventDefault();

            // Close Menu
            Body.addClass('sb-l-c');
            triggerResize();

            // After animation has occured we toggle the menu.
            // Upon the menu reopening the classes will be toggled
            // again, effectively restoring the menus state prior
            // to being hidden
            if (!Body.hasClass('mobile-view')) {
                setTimeout(function () {
                    Body.toggleClass('sb-l-m sb-l-o');
                }, 250);
            }
        });

        // Check window size on load
        // Adds or removes "mobile-view" class based on window size
        var sbOnLoadCheck = function () {
            // Check Body for classes indicating the state of Left and Right Sidebar.
            // If not found add default sidebar settings(sidebar left open, sidebar right closed).
            if (!$('body.sb-l-o').length && !$('body.sb-l-m').length && !$('body.sb-l-c').length) {
                $('body').addClass(options.sbl);
            }
            if (!$('body.sb-r-o').length && !$('body.sb-r-c').length) {
                $('body').addClass(options.sbr);
            }

            // If window is < 1080px wide collapse both sidebars and add ".mobile-view" class
            if ($(window).width() < 1080) {
                Body.removeClass('sb-r-o').addClass('mobile-view sb-l-m sb-r-c');
            }
        };

        // Check window size on resize
        // Adds or removes "mobile-view" class based on window size
        var sbOnResize = function () {
            // If window is < 1080px wide collapse both sidebars and add ".mobile-view" class
            if ($(window).width() < 1080 && !Body.hasClass('mobile-view')) {
                Body.removeClass('sb-r-o').addClass('mobile-view sb-l-m sb-r-c');
            } else if ($(window).width() > 1080) {
                Body.removeClass('mobile-view');
            } else {
                return;
            }
        };

        // Most CSS menu animations are set to 300ms. After this time
        // we trigger a single global window resize to help catch any 3rd
        // party plugins which need the event to resize their given elements
        var triggerResize = function () {
            setTimeout(function () {
                $(window).trigger('resize');
            }, 300);
        };

        // Functions Calls
        sbOnLoadCheck();
        $("#toggle_sidemenu_l").click(sidebarLeftToggle);
        $("body").on('click', '#toggle_sidemenu_r', sidebarRightToggle);

        // Attach debounced resize handler
        var rescale = function () {
            sbOnResize();
        };
        var lazyLayout = _.debounce(rescale, 300);
        $(window).resize(lazyLayout);


        // 2. LEFT USER MENU TOGGLE

        // Find user menu item length
        var usermenuItems = $('.user-menu').find('a');

        // Toggle open the user menu
        $('.sidebar-menu-toggle').click(function (e) {
            e.preventDefault();

            // Toggle Class to signal state change
            $('.user-menu').toggleClass('usermenu-open').slideToggle('fast');

            // If menu is closed apply animation
            if ($('.user-menu').hasClass('usermenu-open')) {
                usermenuItems.addClass('animated fadeIn');
            }

        });

        // 3. LEFT MENU LINKS TOGGLE
        $('.sidebar-menu li a.accordion-toggle').click(function (e) {

            // Any menu item with the accordion class is a dropdown submenu. Thus we prevent default actions
            e.preventDefault();

            // Any menu item with the accordion class is a dropdown submenu. Thus we prevent default actions
            if ($('body').hasClass('sb-l-m') && !$(this).parents('ul.sub-nav').length) {
                return;
            }

            // Any menu item with the accordion class is a dropdown submenu. Thus we prevent default actions
            if (!$(this).parents('ul.sub-nav').length) {
                $('a.accordion-toggle.menu-open').next('ul').slideUp('fast', 'swing', function () {
                    $(this).attr('style', '').prev().removeClass('menu-open');
                });
            }
            // Any menu item with the accordion class is a dropdown submenu. Thus we prevent default actions
            else {
                var activeMenu = $(this).next('ul.sub-nav');
                var siblingMenu = $(this).parent().siblings('li').children('a.accordion-toggle.menu-open').next('ul.sub-nav')

                activeMenu.slideUp('fast', 'swing', function () {
                    $(this).attr('style', '').prev().removeClass('menu-open');
                });
                siblingMenu.slideUp('fast', 'swing', function () {
                    $(this).attr('style', '').prev().removeClass('menu-open');
                });
            }

            // Now we expand targeted menu item, add the ".open-menu" class
            // and remove any left over inline jQuery animation styles
            if (!$(this).hasClass('menu-open')) {
                $(this).next('ul').slideToggle('fast', 'swing', function () {
                    $(this).attr('style', '').prev().toggleClass('menu-open');
                });
            }

        });
    };

    // Tray related Functions
    var runTrays = function () {

        // Match height of tray with the height of body
        var trayMatch = $('.tray[data-tray-height="match"]');
        if (trayMatch.length) {

            // Loop each tray and set height to match body
            trayMatch.each(function () {
                var Height = $('body').height();
                $(this).height(Height);
            });

        }

        // Debounced resize handler
        var rescale = function () {
            if ($(window).width() < 1000) {
                Body.addClass('tray-rescale');
            } else {
                Body.removeClass('tray-rescale tray-rescale-left tray-rescale-right');
            }
        };
        var lazyLayout = _.debounce(rescale, 300);

        if (!Body.hasClass('disable-tray-rescale')) {
            // Rescale on window resize
            $(window).resize(lazyLayout);

            // Rescale on load
            rescale();
        }

    };

    // Form related Functions
    var runFormElements = function () {

        // Init Jquery Sortable, if present
        if ($(".sortable").length) {
            $(".sortable").sortable();
            $(".sortable").disableSelection();
        }

        var Tooltips = $("[data-toggle=tooltip]");

        // Init Bootstrap tooltips, if present
        if (Tooltips.length) {
            if (Tooltips.parents('#sidebar_left')) {
                Tooltips.tooltip({
                    container: $('body'),
                    template: '<div class="tooltip tooltip-white" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
                });
            } else {
                Tooltips.tooltip();
            }
        }

        // Init Bootstrap Popovers, if present
        if ($("[data-toggle=popover]").length) {
            $('[data-toggle=popover]').popover();
        }

        // Init Bootstrap persistent tooltips. This prevents a
        // popup from closing if a checkbox it contains is clicked
        $('.dropdown-menu .dropdown-persist').click(function (event) {
            event.stopPropagation();
        });

        // Prevents a dropdown menu from closing when a navigation
        // menu it contains is clicked (panel/tab menus)
        $('.dropdown-menu .nav-tabs li a').click(function (event) {
            event.preventDefault();
            event.stopPropagation();
            $(this).tab('show')
        });

        // if btn has ".btn-states" class we monitor it for user clicks. On Click we remove
        // the active class from its siblings and give it to the button clicked.
        // This gives the button set a menu like feel or state
        if ($('.btn-states').length) {
            $('.btn-states').click(function () {
                $(this).addClass('active').siblings().removeClass('active');
            });
        }
    };

    var initBackBone = function () {
        var originalSync = Backbone.sync;
        Backbone.sync = function (method, model, options) {
            if (method === 'patch') options.type = 'PUT';
            if (method === 'delete') options.type = 'DELETE';
            return originalSync(method, model, options);
        };
        Backbone.Collection.prototype.save = function (options) {
            Backbone.sync("create", this, options);
        };
        $.ajaxSetup({
            cache: false
        });
    };
    var init = function (options) {

        // Set Default Options
        var defaults = {
            sbl: "sb-l-o", // sidebar left open onload
            sbr: "sb-r-c", // sidebar right closed onload

            collapse: "sb-l-m", // sidebar left collapse style
            siblingRope: true
                // Setting this true will reopen the left sidebar
                // when the right sidebar is closed
        };

        // Extend Default Options.
        var options = $.extend({}, defaults, options);

        // Call Core Functions
        runHelpers();
        runAnimations();
        runSideMenu(options);
        runTrays();
        runFormElements();
        runHeader();
        initBackBone();
    }

    exports.init = init;
});